package com.teamblueplus.comicmaker;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.teamblueplus.brush.*;
import com.teamblueplus.imagecrop.CropOption;
import com.teamblueplus.imagecrop.CropOptionAdapter;
import com.teamblueplus.R;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Activity for draw and crop image
 * 
 * @author qui
 * 
 */
public class ImageEditorMakingActivity extends Activity implements
		View.OnTouchListener, ColorPickerDialog.OnColorChangedListener {

	private ImageEditorSurfaceView ComicSurfaceView;

	// delete later
	// brush feature
	// currentDrawingPath saves all the path for brush functionality
	// its saves each path in an array,
	// private DrawingPath currentDrawingPath;
	private Paint currentPaint;

	private Brush currentBrush;

	private int locX, locY, boundlocX, boundlocY;
	private int isBrushOn;

	private String pathOfImage;
	private boolean rotate;

	static private File APP_FILE_PATH;
	static private ExportBitmapToFile saveFile;

	private static final int FROM_CROP = 1;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.image_editormaking);

		// the path of image to be edited
		pathOfImage = this.getIntent().getExtras().getString("path");
		rotate = false;
		rotate = this.getIntent().getExtras().getBoolean("gallery");

		Log.d("h2", "rotate::" + rotate);
		setCurrentPaint();
		currentBrush = new PenBrush();

		ComicSurfaceView = (ImageEditorSurfaceView) findViewById(R.id.comicSurfaceView);

		ComicSurfaceView.setOnTouchListener(this);

		ComicSurfaceView.setImagePath(pathOfImage, rotate);

		// delete later
		// brush feature
		// do not be confuse with currentDrawingPath and
		// ComicSurfaceView.previewPath
		// ComicSurfaceView.previewPath contains the path for dynamic display on
		// screen
		// ComicSurfaceView.previewPath = new DrawingPath();
		// ComicSurfaceView.previewPath.path = new Path();
		// ComicSurfaceView.previewPath.paint = getPreviewPaint();

		File sdCard = Environment.getExternalStorageDirectory();
		APP_FILE_PATH = new File(sdCard.getAbsolutePath() + "/dimages");

		// brush is disable at first
		isBrushOn = 0;

	}

	private void setCurrentPaint() {
		currentPaint = new Paint();
		currentPaint.setDither(true);
		currentPaint.setColor(0xFFFFFF00);
		currentPaint.setStyle(Paint.Style.STROKE);
		currentPaint.setStrokeJoin(Paint.Join.ROUND);
		currentPaint.setStrokeCap(Paint.Cap.ROUND);
		currentPaint.setStrokeWidth(3);

	}

	private Paint getPreviewPaint() {
		final Paint previewPaint = new Paint();
		previewPaint.setColor(0xFFFFFF00);
		previewPaint.setStyle(Paint.Style.STROKE);
		previewPaint.setStrokeJoin(Paint.Join.ROUND);
		previewPaint.setStrokeCap(Paint.Cap.ROUND);
		previewPaint.setStrokeWidth(3);
		return previewPaint;
	}

	// check if gesture is within the boundaries of the white page
	public void checkBoundaries(MotionEvent motionEvent) {
		locX = (int) motionEvent.getX();
		locY = (int) motionEvent.getY();

		if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
			// gesture is inside the page
			if (locX > 0 && locX < ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getTopPadding()
					&& locY < ComicSurfaceView.getPageHeight()) {
				boundlocX = locX;
				boundlocY = locY;

			}
			// gesture started left border
			else if (locX < 0 && locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = locY;

			}
			// gesture started at left top corner
			else if (locX < 0 && locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = 0;

			}
			// gesture started is at left bottom corner
			else if (locX < 0 && locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = 0;
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at top border
			else if (locY < 0 && locX < ComicSurfaceView.getPageWidth()
					&& locX > 0) {
				boundlocX = locX;
				boundlocY = 0;

			}
			// gesture started at right border
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = locY;

			}
			// gesture started at right top corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = 0;

			}
			// gesture started atright bottom corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at bottom
			else if (locY > ComicSurfaceView.getPageHeight()
					&& locX < ComicSurfaceView.getPageWidth() && locX > 0) {
				boundlocX = locX;
				boundlocY = ComicSurfaceView.getPageHeight();

			}

		} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {

			if (locX > 0 && locX < ComicSurfaceView.getPageWidth() && locY > 0
					&& locY < ComicSurfaceView.getPageHeight()) {
				boundlocX = locX;
				boundlocY = locY;

			}

		} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
			// gesture is inside the page
			if (locX > 0 && locX < ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getTopPadding()
					&& locY < ComicSurfaceView.getPageHeight()) {
				boundlocX = locX;
				boundlocY = locY;

			}
			// gesture started left border
			else if (locX < 0 && locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = locY;

			}
			// gesture started at left top corner
			else if (locX < 0 && locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = 0;
				boundlocY = 0;

			}
			// gesture started is at left bottom corner
			else if (locX < 0 && locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = 0;
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at top border
			else if (locY < ComicSurfaceView.getTopPadding()
					&& locX < ComicSurfaceView.getPageWidth() && locX > 0) {
				boundlocX = locX;
				boundlocY = 0;

			}
			// gesture started at right border
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getPageHeight()
					&& locY > ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = locY;

			}
			// gesture started at right top corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY < ComicSurfaceView.getTopPadding()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = 0;

			}
			// gesture started atright bottom corner
			else if (locX > ComicSurfaceView.getPageWidth()
					&& locY > ComicSurfaceView.getPageHeight()) {
				boundlocX = ComicSurfaceView.getPageWidth();
				boundlocY = ComicSurfaceView.getPageHeight();

			}
			// gesture started at bottom
			else if (locY > ComicSurfaceView.getPageHeight()
					&& locX < ComicSurfaceView.getPageWidth() && locX > 0) {
				boundlocX = locX;
				boundlocY = ComicSurfaceView.getPageHeight();

			}
		}

	}

	// check if brush is on, if on then draw to page
	// public void paintBrush(MotionEvent motionEvent){
	//
	// if(isBrushOn==1){
	// if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
	//
	// this.checkBoundaries(motionEvent);
	// ComicSurfaceView.isDrawing = true;
	//
	// //this is for brush tool
	// //saves the current path from the user
	// currentDrawingPath = new DrawingPath();
	// currentDrawingPath.paint = currentPaint;
	// currentDrawingPath.path = new Path();
	//
	//
	// //test, drag and drop for image
	// //qui fix this, right now it just placing the image base on your touch
	// location
	// // ComicSurfaceView.objBitmapX = boundlocX -
	// ComicSurfaceView._objectBitmap.getWidth()/2;
	// //ComicSurfaceView.objBitmapY = boundlocY -
	// ComicSurfaceView._objectBitmap.getHeight()/2;
	//
	//
	// currentBrush.mouseDown(currentDrawingPath.path, boundlocX, boundlocY);
	// //previewPath is use for dynamic display, so we can display brush path
	// dynamically
	// currentBrush.mouseDown(ComicSurfaceView.previewPath.path, boundlocX,
	// boundlocY);
	//
	// }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){
	//
	// this.checkBoundaries(motionEvent);
	//
	// //test, drag and drop for image
	// // ComicSurfaceView.objBitmapX = boundlocX -
	// ComicSurfaceView._objectBitmap.getWidth()/2;
	// // ComicSurfaceView.objBitmapY = boundlocY -
	// ComicSurfaceView._objectBitmap.getHeight()/2;
	//
	// ComicSurfaceView.isDrawing = true;
	// currentBrush.mouseMove( currentDrawingPath.path, boundlocX, boundlocY );
	// currentBrush.mouseMove(ComicSurfaceView.previewPath.path, boundlocX,
	// boundlocY);
	//
	// }else if(motionEvent.getAction() == MotionEvent.ACTION_UP){
	//
	// this.checkBoundaries(motionEvent);
	// ComicSurfaceView.isDrawing = true;
	//
	// //test, drag and drop for image
	// // ComicSurfaceView.objBitmapX = boundlocX -
	// ComicSurfaceView._objectBitmap.getWidth()/2;
	// // ComicSurfaceView.objBitmapY = boundlocY -
	// ComicSurfaceView._objectBitmap.getHeight()/2;
	//
	//
	// currentBrush.mouseUp(ComicSurfaceView.previewPath.path, boundlocX,
	// boundlocY);
	// ComicSurfaceView.previewPath.path = new Path();
	// ComicSurfaceView.addDrawingPath(currentDrawingPath);
	//
	// currentBrush.mouseUp( currentDrawingPath.path, boundlocX, boundlocY );
	//
	// // undoBtn.setEnabled(true);
	// // redoBtn.setEnabled(false);
	//
	// }
	//
	// }
	//
	// }

	public void paintBrush2(MotionEvent motionEvent) {

		if (this.isBrushOn == 1) {
			int x = (int) motionEvent.getX();
			int y = (int) motionEvent.getY();

			if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
				this.ComicSurfaceView.brush2.touch_start(x, y);

			} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
				this.ComicSurfaceView.brush2.touch_move(x, y);

			} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
				this.ComicSurfaceView.brush2.touch_up();

			}
		}

	}

	@Override
	public boolean onTouch(View view, MotionEvent motionEvent) {

		// check if paint brush is on
		this.paintBrush2(motionEvent);

		if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {

		} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {

		} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {

		}

		return true;
	}

	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.okBtn:
			// save the edited bitmap to file

			this.ComicSurfaceView.isDrawing = false;
			Handler saveHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					setResult(RESULT_OK);
					saveFile = null;

					finish();
					// final AlertDialog alertDialog = new
					// AlertDialog.Builder(currentActivity).create();
					// alertDialog.setTitle("Saved 1");
					// alertDialog.setMessage("Your drawing had been saved :)");
					// alertDialog.setButton("OK", new
					// DialogInterface.OnClickListener() {
					// public void onClick(DialogInterface dialog, int which) {
					//
					// return;
					// }
					// });
					// alertDialog.show();
				}
			};
			saveFile = new ExportBitmapToFile(this, saveHandler,
					ComicSurfaceView.getBitmap(), pathOfImage);
			saveFile.execute();

			break;

		case R.id.cancelBtn:
			// kill activity
			finish();

			break;

		case R.id.brush:
			// flip the value of brush
			isBrushOn = isBrushOn ^ 1;
			break;

		case R.id.crop:
			doCrop();
			break;
		}
	}

	private void doCrop() {
		final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
		Log.d("h2", "doCrop()");
		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setType("image/*");

		// check how many croppipng app are installed
		List<ResolveInfo> list = getPackageManager().queryIntentActivities(
				intent, 0);

		int size = list.size();

		if (size == 0) {
			Toast.makeText(this, "Can not find image crop app",
					Toast.LENGTH_SHORT).show();

			return;
		} else {

			intent.setData(Uri.fromFile(new File(this.pathOfImage)));

			intent.putExtra("outputX", 300);
			intent.putExtra("outputY", 300);
			intent.putExtra("aspectX", 1);
			intent.putExtra("aspectY", 1);
			intent.putExtra("scale", true);
			intent.putExtra("return-data", true);

			// uses the phone crop feature
			if (size == 1) {
				Log.d("h2", "11111");
				Intent i = new Intent(intent);
				ResolveInfo res = list.get(0);

				i.setComponent(new ComponentName(res.activityInfo.packageName,
						res.activityInfo.name));

				startActivityForResult(i, FROM_CROP);
			}
			// ask the user to choose which crop app to use, either the default
			// or custom one
			else {
				Log.d("h2", "22222");

				for (ResolveInfo res : list) {
					final CropOption co = new CropOption();

					co.title = getPackageManager().getApplicationLabel(
							res.activityInfo.applicationInfo);
					co.icon = getPackageManager().getApplicationIcon(
							res.activityInfo.applicationInfo);
					co.appIntent = new Intent(intent);

					co.appIntent
							.setComponent(new ComponentName(
									res.activityInfo.packageName,
									res.activityInfo.name));

					cropOptions.add(co);
				}

				CropOptionAdapter adapter = new CropOptionAdapter(
						getApplicationContext(), cropOptions);

				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle("Choose Crop App");
				builder.setAdapter(adapter,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int item) {
								startActivityForResult(
										cropOptions.get(item).appIntent,
										FROM_CROP);
							}
						});

				builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
					@Override
					public void onCancel(DialogInterface dialog) {

						if (Uri.fromFile(new File(pathOfImage)) != null) {
							getContentResolver().delete(
									Uri.fromFile(new File(pathOfImage)), null,
									null);

						}
					}
				});

				AlertDialog alert = builder.create();

				alert.show();
			}
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != RESULT_OK)
			return;

		switch (requestCode) {
		case FROM_CROP:
			Bundle extras = data.getExtras();
			if (extras != null) {
				Bitmap cropBitmap = extras.getParcelable("data");
				Log.d("h2", "fromCrop");
				ComicSurfaceView._croppedBitmap = cropBitmap;
				ComicSurfaceView.isCropped = true;
			}
			break;
		}
	}

	@Override
	public void onDestroy() {
		ComicSurfaceView.pause();

		ComicSurfaceView = null;

		Log.d("h2", "ImageEditor destroyed");

		super.onDestroy();
	}

	@Override
	public void onPause() {
		Log.d("h2", "ImageEditorActivity paused");
		super.onPause();
		ComicSurfaceView.pause();

	}

	static private class ExportBitmapToFile extends
			AsyncTask<Intent, Void, Boolean> {
		private Context mContext;
		private Handler mHandler;
		private Bitmap nBitmap;
		private String pathToSave;

		public ExportBitmapToFile(Context context, Handler handler,
				Bitmap bitmap, String path) {
			mContext = context;
			nBitmap = bitmap;
			mHandler = handler;
			pathToSave = path;
		}

		@Override
		protected Boolean doInBackground(Intent... arg0) {
			try {
				if (!APP_FILE_PATH.exists()) {
					APP_FILE_PATH.mkdirs();
				}

				final FileOutputStream out = new FileOutputStream(new File(
						pathToSave));
				nBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
				out.flush();
				out.close();
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
			// mHandler.post(completeRunnable);
			return false;
		}

		@Override
		protected void onPostExecute(Boolean bool) {
			super.onPostExecute(bool);
			if (bool) {
				mHandler.sendEmptyMessage(1);
			}
		}
	}

	// use in brush functionality
	private static final int COLOR_MENU_ID = Menu.FIRST;
	private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
	private static final int BLUR_MENU_ID = Menu.FIRST + 2;
	private static final int ERASE_MENU_ID = Menu.FIRST + 3;
	private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
		menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
		menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
		menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
		menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');

		/****
		 * Is this the mechanism to extend with filter effects? Intent intent =
		 * new Intent(null, getIntent().getData());
		 * intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
		 * menu.addIntentOptions( Menu.ALTERNATIVE, 0, new ComponentName(this,
		 * NotesList.class), null, intent, 0, null);
		 *****/
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		this.ComicSurfaceView.brush2.mPaint.setXfermode(null);
		this.ComicSurfaceView.brush2.mPaint.setAlpha(0xFF);

		switch (item.getItemId()) {
		case COLOR_MENU_ID:
			new ColorPickerDialog(this, this,
					this.ComicSurfaceView.brush2.mPaint.getColor()).show();
			return true;
		case EMBOSS_MENU_ID:
			if (this.ComicSurfaceView.brush2.mPaint.getMaskFilter() != this.ComicSurfaceView.brush2.mEmboss) {
				this.ComicSurfaceView.brush2.mPaint
						.setMaskFilter(this.ComicSurfaceView.brush2.mEmboss);
			} else {
				this.ComicSurfaceView.brush2.mPaint.setMaskFilter(null);
			}
			return true;
		case BLUR_MENU_ID:
			if (this.ComicSurfaceView.brush2.mPaint.getMaskFilter() != this.ComicSurfaceView.brush2.mBlur) {
				this.ComicSurfaceView.brush2.mPaint
						.setMaskFilter(this.ComicSurfaceView.brush2.mBlur);
			} else {
				this.ComicSurfaceView.brush2.mPaint.setMaskFilter(null);
			}
			return true;
		case ERASE_MENU_ID:
			this.ComicSurfaceView.brush2.mPaint
					.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
			return true;
		case SRCATOP_MENU_ID:
			this.ComicSurfaceView.brush2.mPaint
					.setXfermode(new PorterDuffXfermode(
							PorterDuff.Mode.SRC_ATOP));
			this.ComicSurfaceView.brush2.mPaint.setAlpha(0x80);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void colorChanged(int color) {
		// TODO Auto-generated method stub
		this.ComicSurfaceView.brush2.mPaint.setColor(color);

	}
}